package d20chat; 

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;


/**
 * Thread dedicated to the connection of one client.
 * When ServerListener detects a new connection, it will give that connection to
 * a new instance of this which will handle all things dealing with that
 * connection.
 * @author Scott
 */
public class ServerThread implements Runnable 
{
    /**
     * The socket associated with a particular instance of ServerThread.
     * Contains the socket of the client.
     */
    private Socket connection;
    /**
     * Stores the actual Thread that this class will run in.
     */
    private Thread ServerThreadThread; //holds the thread
    /**
     * Stores the current instance of Server.
     */
    private Server tempserver; //hold the server class so we can pass messages and errors
    
    

/**
     * Class constructor for ServerThread.
     * Sets up the class and initializes the thread for execution. Does not actually
     * start the new thread running, that is down through StartThread.
     * @param socket The socket that this thread will be tied to.
     * @param theserver Current instance of Server.
     */
    public ServerThread(Socket socket, Server theserver) 
    {
        tempserver = theserver;
        //setup the thread
        ServerThreadThread = new Thread(this);
        //store the connection
        connection = socket;
    }
    
    

/**
     * Starts the thread that will be listening to the connected client.
     * Called externally to fire up the thread.
     */
    public void StartThread()
    {
        ServerThreadThread.start();
    }
    
    
    /**

     */
/**
     * Starting point of the thread.
     * required for threads (thread begins execution in run).
     * Handles the entire loop, listens to incoming messages from the client.
     */
    public void run() 
    {
        InputStream inStream;
        DataInputStream inDataStream;

        String message; //hold the current message

        //these three are use for feedback message
        InetAddress inet = connection.getInetAddress ();
        String origin = inet.getHostName ();
        int originport = connection.getPort ();
        
        //post success info to chat window of server
        //tempserver.ErrorMessageHandler ( "Adding Client: "+origin+":"+originport+"\n" ); 

        //try required for socket stuff
        try  
        {
            //attack stream to the socket
            inStream = connection.getInputStream ();
            inDataStream = new DataInputStream ( inStream );

            //loop until exception is thrown (probably from the socket closing)
            while ( true )  
            {
                //get message from the stream 
                message = inDataStream.readUTF ();
                
                //if message is recieved, send to tempserver
                //probably want to send it to server class instead
                tempserver.GiveMessage(message, connection);
                
            }  // end while
        }  // end try
        //EOF exception seems to be for if they close the connection nicelly
        catch ( EOFException except ) 
        {
            //inform server of connection closed
            
            //tempserver.ErrorMessageHandler ( "ServerThread: Connection closed by Client\n" );
            try  
            {
                //close the connection on our end, and return (closing the thread)
                connection.close ();
                tempserver.someoneLeft(connection);
                return;
            }
            catch ( IOException e )  
            {
                //if we can't close for some reason, just close the thread and let
                //java clean it up
                tempserver.someoneLeft(connection);
                //tempserver.ErrorMessageHandler ( "ServerThread: Unknown error with ServerThread crashing" );
                e.printStackTrace ();
                
                return;
            }  // end IOException
        }  // end catch EOFException
        //all other exceptions (probably from trying to read or write from a dead port)
        catch (SocketException ex)
        {
            tempserver.someoneLeft(connection);
            //tempserver.ErrorMessageHandler ( "ServerThread: Connection closed abormally\n" );
        }
        catch ( IOException e )  
        {
            //print out error and then close out this thread
            tempserver.someoneLeft(connection);
            //tempserver.ErrorMessageHandler ( "ServerThread: Unknown error!\n" );
            e.printStackTrace ();
            return;
        }  // end catch IOException
    }
    
    
}
